inline def degrees_to_radians(degress: Double): Double = degress * math.Pi / 180.0
inline def clamp(x: Double, min: Double, max: Double) =
  if x < min then
    min
  else if x > max then
    max
  else
    x

def reflect(v: Vec3, n: Vec3): Vec3 =
  v - n * dot(v, n) * 2.0

def refract(uv: Vec3, n: Vec3, etai_over_etat: Double): Vec3 =
  val cos_theta = math.min(dot(uv * -1.0, n), 1.0)
  val r_out_perp = (uv + n * cos_theta) * etai_over_etat
  val r_out_parallel = n * -math.sqrt(math.abs(1.0 - r_out_perp.length_squared))
  r_out_parallel + r_out_perp

def reflectance(cosine: Double, ref_idx: Double): Double =
  var r0 = (1 - ref_idx) / (1 + ref_idx)
  r0 = r0 * r0
  r0 + (1- r0) * math.pow(1 - cosine, 5)